package com.pjb.springbootjjwt.store;

import com.pjb.springbootjjwt.store.storage.Handler;
import com.pjb.springbootjjwt.store.storage.csv.CSVHandlerImpl;
import com.pjb.springbootjjwt.store.storage.fun.FunctionHandlerImpl;
import com.pjb.springbootjjwt.store.storage.innodb.HandlerImpl;
import com.pjb.springbootjjwt.store.storage.myisam.MyisamHandlerImpl;
import com.pjb.springbootjjwt.store.storage.procedure.ProcedureHandlerImpl;
import com.pjb.springbootjjwt.store.storage.view.ViewHandlerImpl;
import com.pjb.springbootjjwt.store.utils.FileUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 表结构sql
 */
public class Defines {
    public static String EXT_FRM = ".frm";

    private Defines() {

    }

    /**
     * 获取字段长度
     *
     * @param table
     * @return
     * @throws IOException
     */
    public static List<Integer> fieldsLength(String table) throws IOException {
        String ddl = File.getInstance().getDDL(table);
        return getFieldsLengths(ddl);
    }

    public static int pkLength(String table) throws IOException {
        String ddl = File.getInstance().getDDL(table);
        return getFieldsLengths(ddl).get(Sql.getInstance().getPKIndex(ddl));
    }

    /**
     * 获取字段长度
     *
     * @param ddl
     * @return
     */
    public static List<Integer> getFieldsLengths(String ddl) {
        String[] fields = splitDDL(ddl);
        List<Integer> r = new ArrayList<>();
        if (fields.length > 0)
            for (String field : fields) {
                if (field.contains("key")) continue;
                if (field.contains("(")) {
                    String lenStr = field.substring(field.indexOf("(") + 1, field.indexOf(")"));
                    r.add(Integer.parseInt(lenStr));
                } else {
                    r.add(FileUtil.DEFAULT_SIZE);
                }

            }
        return r;
    }

    /**
     * 拆分ddl
     *
     * @param ddl
     * @return
     */
    public static String[] splitDDL(String ddl) {
        if (StringUtils.isEmpty(ddl)) return new String[]{};

        String subSql = ddl.substring(ddl.indexOf("(") + 1, ddl.lastIndexOf(")"));
        return subSql.split(",");
    }

    /**
     * 获取ddl内字段
     *
     * @param ddl
     * @return
     */
    public static List<String> getFields(String ddl) {
        String[] fields = Defines.splitDDL(ddl);

        List<String> list = new ArrayList<>();
        if (fields.length > 0)
            for (String field : fields) {
                if (field.contains("key")) continue;
                list.add(field.trim().split("\\s+")[0]);
            }
        return list;
    }

    public static String getEngine(String ddl) {
        ddl = ddl.toLowerCase();
        if (ddl.contains("engine")) {
            String sub = ddl.substring(ddl.indexOf("engine"));
            if (sub.contains("innodb")) {
                return "innodb";
            } else if (sub.contains("myisam")) {
                return "myisam";
            } else if (sub.contains("csv")) {
                return "csv";
            } else if (sub.contains("view")) {
                return "view";
            } else if (sub.contains("procedure")) {
                return "procedure";
            } else if (sub.contains("fun")) {
                return "fun";
            }
        }
        return "innodb";
    }

    public static Handler getHandlerByDDL(String ddl) {
        return getHandlerByEngine(getEngine(ddl));
    }

    public static Handler getHandlerByEngine(String engine) {
        switch (engine) {
            case "innodb":
                return new HandlerImpl();
            case "myisam":
                return new MyisamHandlerImpl();
            case "csv":
                return new CSVHandlerImpl();
            case "view":
                return new ViewHandlerImpl();
            case "procedure":
                return new ProcedureHandlerImpl();
            case "fun":
                return new FunctionHandlerImpl();
        }
        return new HandlerImpl();
    }

    public static Handler getHandler(String table) throws IOException {
        String ddl = File.getInstance().getDDL(table);
        return getHandlerByDDL(ddl);
    }
}
